package com.tdcy.framework.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.sql.Types;
import java.util.Scanner;

public class GenerateClass {

	private static final String T = "\t";
	private static final String CRLF = "\r\n";
	private static final String UID = "  private static final long serialVersionUID = 1L;\r\n";

	// 数据库适配器
	public static final String driverName = "oracle.jdbc.driver.OracleDriver";
	// URL
	public static final String url = "jdbc:oracle:thin:@192.168.100.133:1521:orcl";
	// 用户名
	public static final String userName = "wo1mdev";
	// 密码
	public static final String pwd = "wo1mdev";
	// 源文件夹路径
	public static final String srcPath = System.getProperty("user.dir")
			+ "/src/";// "E:/app/new/quicku_manager/src/";
	// 需生成类文件所在包 com/quicku/dao/entity/
	public static final String packagePath = "com/quicku/manager/dao/entity/";// "com/quicku/manager/bean/";
	public static final String className = "HttpNoticeEO";// 生成的类名

	// 需要生成实体类的sql
	public static final String SQL = "select * from http_notice";
	// 需要生成实体类sql所在文件 与SQL二者只需其一就可以
	public static final String sqlPath = "";
	// 表名
	public static final String tableName = "http_notice";
	// 主键,多个用逗号隔开,前后都有逗号 如 ,col1,col2,
	public static final String primaryKey = "http_notice_id";

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			File file = new File(srcPath + packagePath + className + ".java");
			// 防止误操作
			if (file.exists()) {
				System.out.println(className + ".java已存在，是否覆盖？按'n'回车后取消，按回车继续");
				Scanner s = new Scanner(System.in);
				String a;
				while ((a = s.next()) != null) {
					if ("n".equalsIgnoreCase(a))
						return;
					else
						break;
				}
			}
			FileWriter writer = new FileWriter(file);
			writer.write(generateContent());
			writer.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static String generateContent() {
		StringBuffer content = new StringBuffer();
		try {
			content.append("package ").append(packagePath.replaceAll("/", "."));
			if (content.toString().endsWith(".")) {
				content = new StringBuffer(content.toString().substring(0,
						content.toString().length() - 1));
			}
			content.append(";");
			content.append(CRLF);
			StringBuffer importSb = new StringBuffer();
			importSb.append("import java.io.Serializable;");
			importSb.append(CRLF);
			importSb.append("import com.quicku.framework.annotation.Column;");
			importSb.append(CRLF);

			StringBuffer classContent = new StringBuffer();
			StringBuffer funSb = new StringBuffer();
			if (!StringUtils.isEmpty(tableName)) {
				importSb.append("import com.quicku.framework.annotation.Table;");
				importSb.append(CRLF);
				importSb.append("import com.quicku.framework.annotation.Id;");
				importSb.append(CRLF);
				classContent.append("@Table(name = \""
						+ tableName.toUpperCase() + "\")");
				classContent.append(CRLF);
			}
			classContent.append("public class ").append(className);
			classContent.append(" implements Serializable {");
			classContent.append(CRLF);
			classContent.append(UID);

			StringBuffer constructSB = new StringBuffer();
			StringBuffer constructSetSB = new StringBuffer();

			constructSB.append("  public ").append(className).append("(){}")
					.append(CRLF).append(CRLF);
			constructSB.append("  public ").append(className).append("(");

			Class.forName(driverName);
			Connection conn = DriverManager.getConnection(url, userName, pwd);
			Statement stmt = conn.createStatement();
			ResultSet resultSet = stmt.executeQuery(getSQL());
			ResultSetMetaData resultSetMeta = resultSet.getMetaData();
			int columnCount = resultSetMeta.getColumnCount();
			for (int i = 1; i <= columnCount; i++) {
				String columnName = resultSetMeta.getColumnName(i)
						.toLowerCase();
				if (columnName.length() > 40
						|| (columnName.toLowerCase().indexOf("count(") > 0
								|| columnName.toLowerCase().indexOf("sum(") > 0
								|| columnName.toLowerCase().indexOf("avg(") > 0 || columnName
								.toLowerCase().indexOf("decode(") > 0)) {
					throw new Exception(
							"生成实体类，sql字段名命名不合理，长度不能超过40，且不能是表达式或sql函数，【"
									+ columnName + "】");
				}
				int x = 0;
				while ((x = columnName.indexOf("_")) > 0) {// 将以下划线后的第一个字母大写
					char c = columnName.charAt(x + 1);
					columnName = columnName.replaceAll("_" + c,
							String.valueOf(c).toUpperCase());
					x = 0;
				}
				classContent.append(CRLF);
				if (primaryKey.toUpperCase().indexOf(
						"," + resultSetMeta.getColumnName(i).toUpperCase()
								+ ",") >= 0
						|| primaryKey.toUpperCase().equals(
								resultSetMeta.getColumnName(i).toUpperCase())) {
					classContent.append("  @Id");
					classContent.append(CRLF);
				}
				classContent.append("  @Column(name = \""
						+ resultSetMeta.getColumnName(i) + "\")");
				classContent.append(CRLF);

				int columnType = resultSetMeta.getColumnType(i);
				if (columnType == Types.DATE || columnType == Types.TIMESTAMP) {
					if (importSb.toString().indexOf(".util.Date;") < 0) {
						importSb.append("import java.util.Date;");
						importSb.append(CRLF);
					}

					classContent.append("  private Date ").append(columnName)
							.append(";");
					classContent.append(CRLF);
					classContent.append(CRLF);

					constructSB.append("Date ").append(columnName).append(", ");
					constructSetSB.append(T).append("this.").append(columnName)
							.append(" = ").append(columnName).append(";")
							.append(CRLF);

					funSb.append("  public void set").append(
							String.valueOf(columnName.charAt(0)).toUpperCase());
					funSb.append(columnName.substring(1));
					funSb.append("(Date ").append(columnName).append(") {");
					funSb.append(CRLF);
					funSb.append(T);
					funSb.append("this.").append(columnName).append(" = ")
							.append(columnName).append(";");
					funSb.append(CRLF);
					funSb.append("  }");
					funSb.append(CRLF);
					funSb.append(CRLF);

					funSb.append("  public Date get").append(
							String.valueOf(columnName.charAt(0)).toUpperCase());
					funSb.append(columnName.substring(1));
					funSb.append("() {");
					funSb.append(CRLF);
					funSb.append(T);
					funSb.append("return this.").append(columnName).append(";");
					funSb.append(CRLF);
					funSb.append("  }");
					funSb.append(CRLF);
					funSb.append(CRLF);
				} else if (columnType == Types.BIT
						|| columnType == Types.INTEGER) {
					classContent.append("private int ").append(columnName)
							.append(";");
					classContent.append(CRLF);

					constructSB.append("int ").append(columnName).append(", ");
					constructSetSB.append(T).append("this.").append(columnName)
							.append(" = ").append(columnName).append(";")
							.append(CRLF);

					funSb.append("  public void set").append(
							String.valueOf(columnName.charAt(0)).toUpperCase());
					funSb.append(columnName.substring(1));
					funSb.append("(int ").append(columnName).append(") {");
					funSb.append(CRLF);
					funSb.append(T);
					funSb.append("this.").append(columnName).append(" = ")
							.append(columnName).append(";");
					funSb.append(CRLF);
					funSb.append("}");
					funSb.append(CRLF);
					funSb.append(CRLF);

					funSb.append("  public int get").append(
							String.valueOf(columnName.charAt(0)).toUpperCase());
					funSb.append(columnName.substring(1));
					funSb.append("() {");
					funSb.append(CRLF);
					funSb.append(T);
					funSb.append("return this.").append(columnName).append(";");
					funSb.append(CRLF);
					funSb.append("  }");
					funSb.append(CRLF);
					funSb.append(CRLF);
				} else if (columnType == Types.DOUBLE
						|| columnType == Types.FLOAT
						|| columnType == Types.NUMERIC) {
					classContent.append("  private float ").append(columnName)
							.append(";");
					classContent.append(CRLF);

					constructSB.append("float ").append(columnName)
							.append(", ");
					constructSetSB.append(T).append("this.").append(columnName)
							.append(" = ").append(columnName).append(";")
							.append(CRLF);

					funSb.append("  public void set").append(
							String.valueOf(columnName.charAt(0)).toUpperCase());
					funSb.append(columnName.substring(1));
					funSb.append("(float ").append(columnName).append(") {");
					funSb.append(CRLF);
					funSb.append(T);
					funSb.append("this.").append(columnName).append(" = ")
							.append(columnName).append(";");
					funSb.append(CRLF);
					funSb.append("  }");
					funSb.append(CRLF);
					funSb.append(CRLF);

					funSb.append("  public float get").append(
							String.valueOf(columnName.charAt(0)).toUpperCase());
					funSb.append(columnName.substring(1));
					funSb.append("() {");
					funSb.append(CRLF);
					funSb.append(T);
					funSb.append("return this.").append(columnName).append(";");
					funSb.append(CRLF);
					funSb.append("  }");
					funSb.append(CRLF);
					funSb.append(CRLF);
				} else {// 默认为字符串型
					classContent.append("  private String ").append(columnName)
							.append(";");
					classContent.append(CRLF);

					constructSB.append("String ").append(columnName)
							.append(", ");
					constructSetSB.append(T).append("this.").append(columnName)
							.append(" = ").append(columnName).append(";")
							.append(CRLF);

					funSb.append("  public void set").append(
							String.valueOf(columnName.charAt(0)).toUpperCase());
					funSb.append(columnName.substring(1));
					funSb.append("(String ").append(columnName).append(") {");
					funSb.append(CRLF);
					funSb.append(T);
					funSb.append("this.").append(columnName).append(" = ")
							.append(columnName).append(";");
					funSb.append(CRLF);
					funSb.append("  }");
					funSb.append(CRLF);
					funSb.append(CRLF);

					funSb.append("  public String get").append(
							String.valueOf(columnName.charAt(0)).toUpperCase());
					funSb.append(columnName.substring(1));
					funSb.append("() {");
					funSb.append(CRLF);
					funSb.append(T);
					funSb.append("return this.").append(columnName).append(";");
					funSb.append(CRLF);
					funSb.append("  }");
					funSb.append(CRLF);
					funSb.append(CRLF);
				}
			}
			constructSB.delete(constructSB.length() - 2, constructSB.length())
					.append("){").append(CRLF).append(constructSetSB)
					.append("  }").append(CRLF);
			content.append(importSb).append(CRLF).append(classContent)
					.append(CRLF).append(constructSB).append(CRLF)
					.append(funSb);
			content.append("}");
			content.append(CRLF);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return content.toString();
	}

	public static String getSQL() {
		if (!StringUtils.isEmpty(SQL)) {
			return SQL;
		} else {// 从文件读取sql
			File file = new File(sqlPath);
			BufferedReader reader = null;
			try {
				StringBuffer sql = new StringBuffer();
				reader = new BufferedReader(new FileReader(file));
				String tempString = null;
				// 一次读入一行，直到读入null为文件结束
				while ((tempString = reader.readLine()) != null) {
					sql.append(tempString);
				}
				return sql.toString();
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				if (reader != null) {
					try {
						reader.close();
					} catch (IOException e1) {
					}
				}
			}
		}
		return null;
	}

}
